home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
mmv10.zip
/
MMV.C
< prev
next >
Wrap
Text File
|
1989-11-22
|
60KB
|
2,855 lines
/*
mmv 1.0
Copyright (c) 1989 Vladimir Lanin.
This program may be freely used and copied on a non-commercial basis.
Author may be reached at:
lanin@csd2.nyu.edu
Vladimir Lanin
330 Wadsworth Ave, Apt 6F,
New York, NY 10040
*/
/*
Define SYSV to compile under System V.
If your System V has a rename() call, define RENAME.
Otherwise, mmv will only be able to rename directories (via option -r)
when running as the super-user.
There is no reason to set the suid bit on mmv if rename() is available.
It is important that mmv not be run with effective uid set
to any value other than either the real uid or the super-user.
Even when running with effective uid set to super-user,
mmv will only perform actions permitted to the real uid.
Define MSDOS to compile under MS-D*S Turbo C 1.5.
If you prefer mmv's output to use /'s instead of \'s under MS-D*S,
define SLASH.
When neither MSDOS nor SYSV are defined, compiles under BSD.
RENAME is automatically defined under MSDOS and BSD.
If you are running a (UN*X) system that provides the
"struct dirent" readdir() directory reading standard,
define DIRENT. Otherwise, mmv uses the BSD-like
"struct direct" readdir().
If your (UN*X) system has neither of these, get the "dirent"
by Doug Gwyn, available as gwyn-dir-lib in volume 9
of the comp.sources.unix archives.
*/
static char USAGE[] =
#ifdef MSDOS
"Usage: \
%s [-m|x%s|c|o|a|z] [-h] [-d|p] [-g|t] [-v|n] [from to]\n\
\n\
Use #N in the ``to'' pattern to get the string matched\n\
by the N'th ``from'' pattern wildcard.\n";
#define OTHEROPT (_osmajor < 3 ? "" : "|r")
#else
"Usage: \
%s [-m|x|r|c|o|a|l%s] [-h] [-d|p] [-g|t] [-v|n] [from to]\n\
\n\
Use #[l|u]N in the ``to'' pattern to get the [lowercase|uppercase of the]\n\
string matched by the N'th ``from'' pattern wildcard.\n\
\n\
A ``from'' pattern containing wildcards should be quoted when given\n\
on the command line.\n";
#ifdef SYSV
#define OTHEROPT ""
#else
#define OTHEROPT "|s"
#endif
#endif
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#ifdef MSDOS
/* for MS-DOS (under Turbo C 1.5)*/
#include <stdlib.h>
#include <sys/stat.h>
#include <dos.h>
#include <dir.h>
#include <io.h>
#include <fcntl.h>
#define ESC '\''
#ifdef SLASH
#define SLASH '\\'
#define OTHERSLASH '/'
#else
#define SLASH '/'
#define OTHERSLASH '\\'
#endif
typedef int DIRID;
typedef int DEVID;
static char TTY[] = "/dev/con";
extern unsigned _stklen = 10000;
#define RENAME
#else
/* for various flavors of UN*X */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/signal.h>
#include <fcntl.h>
extern char *getenv();
extern long lseek();
extern char *malloc();
#ifdef DIRENT
#include <dirent.h>
typedef struct dirent DIRENTRY;
#else
#ifdef SYSV
#include <sys/dir.h>
/* might need to be changed to <dir.h> */
#else
#include <sys/dir.h>
#endif
typedef struct direct DIRENTRY;
#endif
#define void char /* might want to remove this line */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifndef R_OK
#define R_OK 4
#define W_OK 2
#define X_OK 1
#endif
#define ESC '\\'
#define SLASH '/'
typedef ino_t DIRID;
typedef dev_t DEVID;
#define MAXPATH 1024
static char TTY[] = "/dev/tty";
#ifdef SYSV
/* for System V */
struct utimbuf {
time_t actime;
time_t modtime;
};
#define utimes(f, t) utime((f), (t))
#else
/* for BSD */
#define RENAME
#include <sys/time.h>
#endif
#endif
#define mylower(c) (isupper(c) ? (c)-'A'+'a' : (c))
#define myupper(c) (islower(c) ? (c)-'a'+'A' : (c))
#define STRLEN(s) (sizeof(s) - 1)
#define mydup(s) (strcpy((char *)challoc(strlen(s) + 1, 0), (s)))
#define DFLT 0x001
#define NORMCOPY 0x002
#define OVERWRITE 0x004
#define NORMMOVE 0x008
#define XMOVE 0x010
#define DIRMOVE 0x020
#define NORMAPPEND 0x040
#define ZAPPEND 0x080
#define HARDLINK 0x100
#define SYMLINK 0x200
#define COPY (NORMCOPY | OVERWRITE)
#define MOVE (NORMMOVE | XMOVE | DIRMOVE)
#define APPEND (NORMAPPEND | ZAPPEND)
#define LINK (HARDLINK | SYMLINK)
static char MOVENAME[] = "mmv";
static char COPYNAME[] = "mcp";
static char APPENDNAME[] = "mad";
static char LINKNAME[] = "mln";
#define ASKDEL 0
#define ALLDEL 1
#define NODEL 2
#define ASKBAD 0
#define SKIPBAD 1
#define ABORTBAD 2
#define STAY 0
#define LOWER 1
#define UPPER 2
#define MAXWILD 20
#define MAXPATLEN MAXPATH
#define INITROOM 10
#define CHUNKSIZE 2048
#define BUFSIZE 4096
#define FI_STTAKEN 0x01
#define FI_LINKERR 0x02
#define FI_INSTICKY 0x04
#define FI_NODEL 0x08
#define FI_KNOWWRITE 0x010
#define FI_CANWRITE 0x20
#define FI_ISDIR 0x40
#define FI_ISLNK 0x80
typedef struct {
char *fi_name;
struct rep *fi_rep;
#ifdef MSDOS
char fi_attrib;
#else
short fi_mode;
char fi_stflags;
#endif
} FILEINFO;
#define DI_KNOWWRITE 0x01
#define DI_CANWRITE 0x02
#define DI_CLEANED 0x04
typedef struct {
DEVID di_vid;
DIRID di_did;
unsigned di_nfils;
FILEINFO **di_fils;
char di_flags;
} DIRINFO;
#define H_NODIR 1
#define H_NOREADDIR 2
typedef struct {
char *h_name;
DIRINFO *h_di;
char h_err;
} HANDLE;
#define R_ISX 0x01
#define R_SKIP 0x02
#define R_DELOK 0x04
#define R_ISALIASED 0x08
#define R_ISCYCLE 0x10
#define R_ONEDIRLINK 0x20
typedef struct rep {
HANDLE *r_hfrom;
FILEINFO *r_ffrom;
HANDLE *r_hto;
char *r_nto; /* non-path part of new name */
FILEINFO *r_fdel;
struct rep *r_first;
struct rep *r_thendo;
struct rep *r_next;
char r_flags;
} REP;
typedef struct {
REP *rd_p;
DIRINFO *rd_dto;
char *rd_nto;
unsigned rd_i;
} REPDICT;
typedef struct chunk {
struct chunk *ch_next;
unsigned ch_len;
} CHUNK;
typedef struct {
CHUNK *sl_first;
char *sl_unused;
int sl_len;
} SLICER;
static void init(/* */);
static void procargs(/* int argc, char **argv,
char **pfrompat, char **ptopat */);
static void matchpats(/* char *cfrom, char *cto */);
static int getpat(/* */);
static int getword(/* char *buf */);
static void matchpat(/* */);
static int parsepat(/* */);
static int dostage(/* char *lastend, char *pathend,
char **start1, int *len1, int stage, int anylev */);
static int trymatch(/* FILEINFO *ffrom, char *pat */);
static int keepmatch(/* FILEINFO *ffrom, char *pathend,
int *pk, int needslash, int dirs, int fils */);
static int badrep(/* HANDLE *hfrom, FILEINFO *ffrom,
HANDLE **phto, char **pnto, FILEINFO **pfdel, int *pflags */);
static int checkto(/* HANDLE *hfrom, char *f,
HANDLE **phto, char **pnto, FILEINFO **pfdel */);
static char *getpath(/* char *tpath */);
static int badname(/* char *s */);
static FILEINFO *fsearch(/* char *s, DIRINFO *d */);
static int ffirst(/* char *s, int n, DIRINFO *d */);
static HANDLE *checkdir(/* char *p, char *pathend, int which */);
static void takedir(/*
char *p, DIRINFO *di, int sticky
or
struct ffblk *pff, DIRINFO *di
*/);
static int fcmp(/* FILEINFO **pf1, FILEINFO **pf2 */);
static HANDLE *hadd(/* char *n */);
static int hsearch(/* char *n, int which, HANDLE **ph */);
static DIRINFO *dadd(/* DEVID v, DIRID d */);
static DIRINFO *dsearch(/* DEVID v, DIRID d */);
static int match(/* char *pat, char *s, char **start1, int *len1 */);
static void makerep(/* */);
static void checkcollisions(/* */);
static int rdcmp(/* REPDICT *rd1, REPDICT *rd2 */);
static void findorder(/* */);
static void scandeletes(/* int (*pkilldel)(REP *p) */);
static int baddel(/* REP *p */);
static int skipdel(/* REP *p */);
static void nochains(/* */);
static void printchain(/* REP *p */);
static void goonordie(/* */);
static void doreps(/* */);
static long appendalias(/* REP *first, REP *p, int *pprintaliased */);
static int movealias(/* REP *first, REP *p, int *pprintaliased */);
static int snap(/* REP *first, REP *p */);
static void showdone(/* REP *fin */);
static void breakout(/* */);
static int breakrep(/* */);
static void breakstat(/* */);
static void quit(/* */);
static int copymove(/* REP *p */);
static int copy(/* FI